<script lang="ts" setup>
import { QForm, type FormItemRows } from '@meetjs/element-plus-kit'
import { type FormRules } from 'element-plus'
import { getDicts } from '@/api/system/dict/index'
import { validEmailReg, validPhoneReg } from '@/utils/validate'
import type { DeptTree, UserParams } from '@/api/system/user/type'
import { getConfigKey } from '@/api/system/config'
import type { IGetDictsRes } from '@/api/system/dict/type'
import { addUser, getUser, updateUser } from '@/api/system/user/index'

const props = defineProps<{
	deptOptions: DeptTree[]
}>()

const userId = ref('')
const originInitPassword = ref('')

const emits = defineEmits<{
	refresh: []
}>()
const visible = ref(false)
const loading = ref(false)
const formLoading = ref(false)
const btnLoading = computed(() => loading.value || formLoading.value)

const title = ref<'新增用户' | '修改用户'>('新增用户')
// TODO:后续优化类型
const formRef = ref()
const baseFormData: UserParams = {
	nickName: '',
	deptId: undefined,
	phoneNumber: '',
	email: '',
	userName: '',
	password: '',
	sex: 0,
	status: 0,
	postIds: [],
	roleIds: [],
	remark: ''
}

const cacheEnabledDeptOptions = computed(() => filterDisabledDept(JSON.parse(JSON.stringify(props.deptOptions))))
const sysUserSex = ref<IGetDictsRes>([])
const sysNormalDisable = ref<IGetDictsRes>([])
const postIdsOptions = ref<IGetDictsRes>([])
const roleIdsOptions = ref<IGetDictsRes>([])

const dialogFormValue = ref<UserParams>({ ...baseFormData })
const hiden = computed(() => (userId.value ? 'display: none' : ''))
const dialogOptions = ref<FormItemRows[]>([
	{
		type: 'input',
		label: '用户昵称',
		prop: 'nickName',
		attrs: {
			maxlength: 30
		}
	},
	{
		type: 'cascader',
		label: '归属部门',
		prop: 'deptId',
		attrs: {
			props: {
				value: 'id',
				label: 'label',
				children: 'children',
				emitPath: false,
				checkStrictly: true
			}
		},
		options: cacheEnabledDeptOptions as unknown as any[]
	},
	{
		type: 'input',
		label: '手机号码',
		prop: 'phoneNumber',
		attrs: {
			maxlength: 11
		}
	},
	{
		type: 'input',
		label: '邮箱',
		prop: 'email',
		attrs: {
			maxlength: 50
		}
	},

	{
		type: 'input',
		label: '用户名称',
		prop: 'userName',
		attrs: {
			maxlength: 30,
			style: userId.value ? 'display: none' : ''
		},
		formItem: {
			style: hiden
		}
	},
	{
		type: 'input',
		label: '用户密码',
		prop: 'password',
		attrs: {
			showPassword: true,
			type: 'password',
			maxlength: 20
		},
		formItem: {
			style: hiden
		}
	},

	{
		type: 'select',
		label: '用户性别',
		prop: 'sex',
		options: sysUserSex as unknown as any[]
	},
	{
		type: 'radio',
		label: '状态',
		prop: 'status',
		options: sysNormalDisable as unknown as any[]
	},

	{
		type: 'select',
		label: '岗位',
		prop: 'postIds',
		attrs: {
			multiple: true
		},
		options: postIdsOptions as unknown as any[]
	},
	{
		type: 'select',
		label: '角色',
		prop: 'roleIds',
		attrs: {
			multiple: true
		},
		options: roleIdsOptions as unknown as any[]
	},
	{
		type: 'textarea',
		label: '备注',
		prop: 'remark',
		attrs: {
			rows: 3
		}
	}
])

const baseRule = {
	nickName: [
		{
			required: true,
			message: '用户昵称不能为空',
			trigger: 'blur'
		}
	],

	email: [
		{
			pattern: validEmailReg,
			message: '请输入正确的邮箱地址',
			trigger: ['blur', 'change']
		}
	],
	phoneNumber: [
		{
			required: true,
			message: '手机号码不能为空',
			trigger: 'blur'
		},
		{
			pattern: validPhoneReg,
			message: '请输入正确的手机号码',
			trigger: 'blur'
		}
	],
	userName: [
		{
			required: true,
			message: '用户名称不能为空',
			trigger: 'blur'
		},
		{
			min: 2,
			max: 20,
			message: '用户名称长度必须介于 2 和 20 之间',
			trigger: 'blur'
		}
	],
	password: [
		{
			required: true,
			message: '用户密码不能为空',
			trigger: 'blur'
		},
		{
			min: 5,
			max: 20,
			message: '用户密码长度必须介于 5 和 20 之间',
			trigger: 'blur'
		},
		{
			pattern: /^[^<>"'|\\]+$/,
			message: '不能包含非法字符：< > " \' \\ |',
			trigger: 'blur'
		}
	]
}
const rules = ref<FormRules<{ [k: string]: any }>>({ ...baseRule })

/** 过滤禁用的部门 */
function filterDisabledDept(deptList: DeptTree[]) {
	return deptList.filter(dept => {
		if (dept.disabled) {
			return false
		}
		if (dept.children && dept.children.length) {
			dept.children = filterDisabledDept(dept.children)
		}
		return true
	})
}
const init = async (type: 'add' | 'edit', editUserId = '') => {
	visible.value = true
	title.value = type === 'add' ? '新增用户' : '修改用户'
	userId.value = editUserId
	if (type === 'add') {
		rules.value = { ...baseRule }
	} else {
		rules.value = {
			...baseRule,
			userName: [],
			password: []
		}
	}
	// 新增默认password
	if (!userId.value && originInitPassword.value && !dialogFormValue.value.password) {
		dialogFormValue.value.password = originInitPassword.value
	}
	try {
		formLoading.value = true
		const { data } = await getUser(userId.value + '')
		postIdsOptions.value = data.posts.map(v => ({
			label: v.postName,
			value: v.id
		}))
		roleIdsOptions.value = data.roles.map(v => ({
			label: v.roleName,
			value: v.id
		}))

		if (data.data) {
			// Object.keys(dialogFormValue.value).forEach(key => {
			// 	if (Object.prototype.hasOwnProperty.call(data.data, key)) {
			// 		dialogFormValue.value[key] = data.data[key]
			// 	}
			// })
			dialogFormValue.value = {
				...dialogFormValue.value,
				...data.data
			}
		} else {
			dialogFormValue.value = { ...baseFormData }
		}
		if (data.postIds) dialogFormValue.value.postIds = data.postIds
		if (data.roleIds) dialogFormValue.value.roleIds = data.roleIds
		console.log('data', dialogFormValue.value)
	} finally {
		formLoading.value = false
		setTimeout(() => {
			formRef.value?.clearValidate()
		})
	}
}

const submit = () => {
	formRef.value?.validate(async (vaild: boolean) => {
		if (vaild) {
			try {
				loading.value = true
				const apiFunc = title.value === '新增用户' ? addUser : updateUser
				await apiFunc({ ...dialogFormValue.value })
				const message = title.value === '新增用户' ? '新增成功' : '修改成功'
				ElMessage.success(message)
				visible.value = false
				emits('refresh')
			} finally {
				loading.value = false
			}
		}
	})
}
const handelClose = () => {
	formRef.value?.resetFields()
	formRef.value?.clearValidate()
}
function initOptions() {
	getDicts('sys_sys_user_sex').then(data => {
		sysUserSex.value = data
	})
	getDicts('sys_sys_normal_disable').then(data => {
		sysNormalDisable.value = data
	})

	getConfigKey('sys.user.initPassword').then(data => {
		dialogFormValue.value.password = data.msg
		originInitPassword.value = data.msg
	})
}
initOptions()
defineExpose({
	init
})
</script>
<template>
	<ElDialog
		v-model="visible"
		:title="title"
		:close-on-click-modal="false"
		width="800px"
		@close="handelClose"
	>
		<div v-loading="formLoading">
			<QForm
				ref="formRef"
				label-width="120px"
				:model="dialogFormValue"
				:form-options="dialogOptions"
				:rules="rules"
			/>
		</div>
		<template #footer>
			<el-button @click="visible = false">取消</el-button>
			<el-button
				type="primary"
				:loading="btnLoading"
				@click="submit"
			>
				确定
			</el-button>
		</template>
	</ElDialog>
</template>

<style lang="scss" scoped></style>
